#ifndef __HTTP_PROT_BUFFER_H_
#define __HTTP_PROT_BUFFER_H_

#include <vector>


namespace httpprot
{
	class Buffer
	{
	public:
		class Range
		{
		public:
			Range( ) :
				m_offset( 0 ),
				m_size( 0 )
			{
			}

			unsigned int GetSize( ) const
			{
				return getSize( );
			}

			Range MakeSubRange( unsigned int offset, unsigned int size ) const
			{
				if( offset >= m_size )
					return Range( );
				if( offset + size > m_size )
					return Range( );
				return Range( m_offset + offset, size );
			}

		private:
		friend class Buffer;

			Range( unsigned int offset, unsigned int size ) :
				m_offset( offset ),
				m_size( size )
			{
			}

			unsigned int getOffset( ) const
			{
				return m_offset;
			}

			unsigned int getSize( ) const
			{
				return m_size;
			}

		private:
			unsigned int m_offset;
			unsigned int m_size;
		};

	public:
		Buffer( )
		{
		}

		void ReadBytes( const Range& range, char * bufferOut )
		{
			unsigned int rangeSize = range.GetSize( );
			unsigned int rangeOffset = range.getOffset( );
			for( unsigned int i = 0; i < rangeSize; ++i )
				bufferOut[ i ] = m_buffer[ rangeOffset + i ];
		}

		void ReadBytes( const Range& range, std::vector< char >& bufferOut )
		{
			bufferOut.clear( );

			unsigned int rangeSize = range.GetSize( );
			if( rangeSize )
			{
				bufferOut.resize( rangeSize );
				ReadBytes( range, &bufferOut[ 0 ] );
			}
		}

		template< typename IteratorType >
		void AddBytes( IteratorType b, IteratorType e )
		{
			m_buffer.insert( m_buffer.end( ), b, e );
		}

		void RemoveBytesFromFront( unsigned int numBytes )
		{
			unsigned int bufferSize = m_buffer.size( );
			if( numBytes > bufferSize )
				numBytes = bufferSize;
			m_buffer.erase( m_buffer.begin( ), m_buffer.begin( ) + numBytes );
		}

	private:
		std::vector< char > m_buffer;
	};
};

#endif